﻿using System;
using System.Diagnostics; // Process Class
using System.Windows;

namespace AFT
{
    /* Device Information Loader
     * Build Version
     * Bootloader
     * Radio ?? 먼지 모르겠음
     * Network - 통신사
     * Kernel 
     * Model Name
     * Serial
     * 
     * 
     * 
     */
    class DeviceInformationLoader
    {
        public string buildVersion;
        public string bootLoader;
        public string radio;
        public string network;
        public string kernelVersion;
        public string uptime;
        public string modelName;
        public string serial;
        public DiskInformation diskInformation;
        public ProcessInformation processInformation;
        public NetworkCfg networkCfg;
        public NetworkState networkState;


        ~DeviceInformationLoader()
        {

        }


        private void cmdProcess_Exited(object sender, System.EventArgs e)
        {
            //가져오기 완료하면 이벤트 발생
        }

        private void connected_ADB(object sender, System.EventArgs e)
        {
            //MessageBox.Show("Run ADB.");
        }

        public int getDeviceInformation()
        {
            if (    getBasicInformation()       == -1   || 
                    getDiskInformation()        == -1   || 
                    getProcessInformation()     == -1   ||
                    getNetworkCfg()             == -1   ||
                    getNetworkState()           == -1         )
                return -1;
            
            return 1;
        }

        private int getCpuInformation()
        {
            return 1;
        }

        public int runADB()
        {
            Process process = new Process();

            //process.StartInfo.WorkingDirectory = "C:\\Program Files\\Android\\android-sdk\\platform-tools";
            process.StartInfo.FileName = "adb.exe";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            process.StartInfo.CreateNoWindow = true;
            process.EnableRaisingEvents = true;
            process.StartInfo.Arguments = "device";
            process.Exited += new EventHandler(connected_ADB);

            if (process.Start())
                return 1;
            else
                return 0;

            /*
             * ADB 실행되어있는지 체크해야됨. 
             */
        }

        private Process runADB(string directory, string filename, string argument)
        {
            Process process = new Process();
            process.StartInfo.WorkingDirectory = directory;
            process.StartInfo.FileName = filename;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.Arguments = argument;
            process.EnableRaisingEvents = true;
            process.Exited += new EventHandler(cmdProcess_Exited);
            process.Start();
            return process;
        }

        private int getBasicInformation()
        {
            /*
            Process process = new Process();
            process.StartInfo.WorkingDirectory = "C:\\Program Files\\Android\\android-sdk\\platform-tools";
            process.StartInfo.FileName = "adb.exe";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.Arguments = "bugreport";
            process.EnableRaisingEvents = true;
            process.Exited += new EventHandler(cmdProcess_Exited);
            process.Start();
            */



            Process process = runADB("C:\\Program Files\\Android\\android-sdk\\platform-tools", "adb.exe", "bugreport");
            string[] outputStream = new string[25];
            for (int i = 0; i < 25; i++)
            {
                outputStream[i] = process.StandardOutput.ReadLine();
            }

            process.Kill();

            if (outputStream[0] == null)
            {
                return -1;
            }
            else
            {
                buildVersion = outputStream[8].Substring(7);
                bootLoader = outputStream[10].Substring(12);
                radio = outputStream[12].Substring(7);
                network = outputStream[14].Substring(9);
                kernelVersion = outputStream[16].Substring(8);
                uptime = outputStream[24].Substring(9, 8);
            }



            process = runADB("C:\\Program Files\\Android\\android-sdk\\platform-tools", "adb.exe", "shell cat /proc/cpuinfo");
            outputStream = new string[1];
            
            outputStream[0] = process.StandardOutput.ReadToEnd();
            
            if (outputStream[0] == null)
            {
                return -1;
            }
            else
            {
                int start = outputStream[0].IndexOf("Hardware\t: ") + 11;
                modelName = outputStream[0].Substring(start);
                int end = modelName.IndexOf("\r\r\nRevision\t:");
                modelName = modelName.Remove(end);

                start = outputStream[0].IndexOf("Serial\t\t: ") + 10;
                serial = outputStream[0].Substring(start);
                end = serial.IndexOf("\r\r\n");
                serial = serial.Remove(end);
            }
            return 1;
        }

        private int getDiskInformation()
        {
            Process process = runADB("C:\\Program Files\\Android\\android-sdk\\platform-tools", "adb.exe", "shell df");

            string outputStream = "";
            diskInformation = new DiskInformation();

            while( !process.StandardOutput.EndOfStream )
            {
                outputStream = process.StandardOutput.ReadLine();
                int i = 0;
                if( outputStream != "" && outputStream[0] == '/' )
                {

                    string fileSystem = "";
                    string totalSize = "";
                    string usedSize = "";
                    string freeSize = "";
                    string blkSize = "";

                    for ( i = 0; outputStream[i] != ' ' ; i++ )
                    {
                        fileSystem += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        totalSize += outputStream[i];
                    }

                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        usedSize += outputStream[i];
                    }

                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        freeSize += outputStream[i];
                    }

                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    blkSize = outputStream;


                    diskInformation.addDisk( fileSystem, totalSize, usedSize, freeSize, blkSize );
                    
                }

            }
            return 1;
        }

        private int getProcessInformation()
        {
            Process process = runADB("C:\\Program Files\\Android\\android-sdk\\platform-tools", "adb.exe", "shell ps -p");
            
            string outputStream = "";
            processInformation = new ProcessInformation();

            process.StandardOutput.ReadLine();
            while( !process.StandardOutput.EndOfStream )
            {
                outputStream = process.StandardOutput.ReadLine();
                int i = 0;
                if (outputStream != "")
                {
                    string user = "";
                    string pid = "";
                    string ppid = "";
                    string vsize = "";
                    string rss = "";
                    string prio = "";
                    string nice = "";
                    string rtpri = "";
                    string sched = "";
                    string wchan = "";
                    string pc = "";
                    string name = "";

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        user += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        pid += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        ppid += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        vsize += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        rss += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        prio += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        nice += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        rtpri += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        sched += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        wchan += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        pc += outputStream[i];
                    }

                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
 
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    name = outputStream;

                    processInformation.addProcess( user, 
                                                pid, 
                                                ppid, 
                                                vsize, 
                                                rss, 
                                                prio, 
                                                nice, 
                                                rtpri,
                                                sched,
                                                wchan,
                                                pc,
                                                name    );

                }
            }

            return 1;
        }

        private int getNetworkCfg()
        {
            Process process = runADB("C:\\Program Files\\Android\\android-sdk\\platform-tools", "adb.exe", "shell netcfg");
            
            string outputStream = "";

            networkCfg = new NetworkCfg();

            while (!process.StandardOutput.EndOfStream)
            {

                outputStream = process.StandardOutput.ReadLine();
                int i = 0;

                if (outputStream != "")
                {
                    string name = "";
                    string state = "";
                    string ipaddr = "";
                    string macaddr = "";

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        name += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        state += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        ipaddr += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
 
                    }

                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    macaddr = outputStream;

                    networkCfg.addNetworkCfg(name, state, ipaddr, macaddr);
                }
            }
            return 1;
        }


        private int getNetworkState()
        {
            Process process = runADB("C:\\Program Files\\Android\\android-sdk\\platform-tools", "adb.exe", "shell netstat");
            
            string outputStream = "";

            networkState = new NetworkState();

            process.StandardOutput.ReadLine();
            while (!process.StandardOutput.EndOfStream)
            {
                outputStream = process.StandardOutput.ReadLine();
                int i = 0;

                if (outputStream != "")
                {
                    string protocol = "";
                    string recvQ = "";
                    string sendQ = "";
                    string localaddr = "";
                    string foreignaddr = "";
                    string state = "";

                    for (i = 0; i < 4 ; i++)
                    {
                        protocol += outputStream[i];
                    }
                    protocol.Trim();
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        recvQ += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        sendQ += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        localaddr += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    for (i = 0; outputStream[i] != ' '; i++)
                    {
                        foreignaddr += outputStream[i];
                    }
                    outputStream = outputStream.Substring(i);
                    outputStream = outputStream.Trim();

                    state = outputStream;

                    networkState.addNetworkState(   protocol,
                                                    recvQ,
                                                    sendQ,
                                                    localaddr,
                                                    foreignaddr,
                                                    state);
                }
            }

            return 1;
        }
    }
}
